From 8524efb00746a39a562c6ef0087addd9481042ad Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 1 Oct 2015 23:48:47 -0700 Subject: [PATCH] Add helper functions for reading/writing whole files Adds some helpful error text if an error happens as well --- src/cargo/ops/cargo_new.rs | 19 +++++++---------- src/cargo/ops/cargo_rustc/custom_build.rs | 21 ++++++------------- src/cargo/ops/lockfile.rs | 4 ++-- src/cargo/ops/registry.rs | 14 +++---------- src/cargo/sources/registry.rs | 8 +++----- src/cargo/util/config.rs | 10 ++++----- src/cargo/util/paths.rs | 25 ++++++++++++++++++++++- 7 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index 5b36097b3..c3a6e5acb 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -1,7 +1,6 @@ use std::env; -use std::fs::{self, File}; +use std::fs; use std::io::prelude::*; -use std::io; use std::path::Path; use rustc_serialize::{Decodable, Decoder}; @@ -11,7 +10,7 @@ use git2::Config as GitConfig; use term::color::BLACK; use util::{GitRepo, HgRepo, CargoResult, human, ChainError, internal}; -use util::Config; +use util::{Config, paths}; use toml; @@ -102,10 +101,6 @@ fn existing_vcs_repo(path: &Path) -> bool { GitRepo::discover(path).is_ok() || HgRepo::discover(path).is_ok() } -fn file(p: &Path, contents: &[u8]) -> io::Result<()> { - try!(File::create(p)).write_all(contents) -} - fn mk(config: &Config, path: &Path, name: &str, opts: &NewOptions) -> CargoResult<()> { let cfg = try!(global_config(config)); @@ -125,11 +120,11 @@ fn mk(config: &Config, path: &Path, name: &str, match vcs { VersionControl::Git => { try!(GitRepo::init(path)); - try!(file(&path.join(".gitignore"), ignore.as_bytes())); + try!(paths::write(&path.join(".gitignore"), ignore.as_bytes())); }, VersionControl::Hg => { try!(HgRepo::init(path)); - try!(file(&path.join(".hgignore"), ignore.as_bytes())); + try!(paths::write(&path.join(".hgignore"), ignore.as_bytes())); }, VersionControl::NoVcs => { try!(fs::create_dir(path)); @@ -147,7 +142,7 @@ fn mk(config: &Config, path: &Path, name: &str, (None, None, name, None) => name, }; - try!(file(&path.join("Cargo.toml"), format!( + try!(paths::write(&path.join("Cargo.toml"), format!( r#"[package] name = "{}" version = "0.1.0" @@ -157,13 +152,13 @@ authors = [{}] try!(fs::create_dir(&path.join("src"))); if opts.bin { - try!(file(&path.join("src/main.rs"), b"\ + try!(paths::write(&path.join("src/main.rs"), b"\ fn main() { println!(\"Hello, world!\"); } ")); } else { - try!(file(&path.join("src/lib.rs"), b"\ + try!(paths::write(&path.join("src/lib.rs"), b"\ #[test] fn it_works() { } diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index 28348bd62..7967a1a4d 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use std::fs::{self, File}; +use std::fs; use std::io::prelude::*; use std::path::PathBuf; use std::str; @@ -7,7 +7,7 @@ use std::sync::{Mutex, Arc}; use core::{PackageId, PackageSet}; use util::{CargoResult, human, Human}; -use util::{internal, ChainError, profile}; +use util::{internal, ChainError, profile, paths}; use util::Freshness; use super::job::Work; @@ -174,13 +174,8 @@ pub fn prepare(cx: &mut Context, unit: &Unit) let parsed_output = try!(BuildOutput::parse(output, &pkg_name)); build_state.insert(id, kind, parsed_output); - try!(File::create(&build_output.parent().unwrap().join("output")) - .and_then(|mut f| f.write_all(output.as_bytes())) - .map_err(|e| { - human(format!("failed to write output of custom build command: {}", - e)) - })); - + try!(paths::write(&build_output.parent().unwrap().join("output"), + output.as_bytes())); Ok(()) }); @@ -198,12 +193,8 @@ pub fn prepare(cx: &mut Context, unit: &Unit) let dirty = work.then(dirty); let fresh = Work::new(move |_tx| { let (id, pkg_name, build_state, build_output) = all; - let new_loc = build_output.parent().unwrap().join("output"); - let mut f = try!(File::open(&new_loc).map_err(|e| { - human(format!("failed to read cached build command output: {}", e)) - })); - let mut contents = String::new(); - try!(f.read_to_string(&mut contents)); + let contents = try!(paths::read(&build_output.parent().unwrap() + .join("output"))); let output = try!(BuildOutput::parse(&contents, &pkg_name)); build_state.insert(id, kind, output); Ok(()) diff --git a/src/cargo/ops/lockfile.rs b/src/cargo/ops/lockfile.rs index 12e08c071..da8aac7a1 100644 --- a/src/cargo/ops/lockfile.rs +++ b/src/cargo/ops/lockfile.rs @@ -6,7 +6,7 @@ use rustc_serialize::{Encodable, Decodable}; use toml::{self, Encoder, Value}; use core::{Resolve, resolver, Package, SourceId}; -use util::{CargoResult, ChainError, human}; +use util::{CargoResult, ChainError, human, paths}; use util::toml as cargo_toml; pub fn load_pkg_lockfile(pkg: &Package) -> CargoResult> { @@ -68,7 +68,7 @@ pub fn write_lockfile(dst: &Path, resolve: &Resolve) -> CargoResult<()> { None => {} } - try!(try!(File::create(dst)).write_all(out.as_bytes())); + try!(paths::write(dst, out.as_bytes())); Ok(()) } diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index d526dc7fc..75ee24c2d 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use std::env; -use std::fs::{self, File}; +use std::fs; use std::io::prelude::*; use std::iter::repeat; use std::path::{Path, PathBuf}; @@ -17,6 +17,7 @@ use core::manifest::ManifestMetadata; use ops; use sources::{RegistrySource}; use util::config; +use util::paths; use util::{CargoResult, human, ChainError, ToUrl}; use util::config::{Config, ConfigValue, Location}; use util::important_paths::find_root_manifest_for_cwd; @@ -92,16 +93,7 @@ fn transmit(pkg: &Package, tarball: &Path, registry: &mut Registry) ref keywords, ref readme, ref repository, ref license, ref license_file, } = *manifest.metadata(); let readme = match *readme { - Some(ref readme) => { - let path = pkg.root().join(readme); - let mut contents = String::new(); - try!(File::open(&path).and_then(|mut f| { - f.read_to_string(&mut contents) - }).chain_error(|| { - human("failed to read the specified README") - })); - Some(contents) - } + Some(ref readme) => Some(try!(paths::read(&pkg.root().join(readme)))), None => None, }; match *license_file { diff --git a/src/cargo/sources/registry.rs b/src/cargo/sources/registry.rs index b9754852d..3d0c67dca 100644 --- a/src/cargo/sources/registry.rs +++ b/src/cargo/sources/registry.rs @@ -175,7 +175,7 @@ use core::{Source, SourceId, PackageId, Package, Summary, Registry}; use core::dependency::{Dependency, DependencyInner, Kind}; use sources::{PathSource, git}; use util::{CargoResult, Config, internal, ChainError, ToUrl, human}; -use util::{hex, Sha256}; +use util::{hex, Sha256, paths}; use ops; static DEFAULT: &'static str = "https://github.com/rust-lang/crates.io-index"; @@ -265,9 +265,7 @@ impl<'cfg> RegistrySource<'cfg> { /// /// This requires that the index has been at least checked out. pub fn config(&self) -> CargoResult { - let mut f = try!(File::open(&self.checkout_path.join("config.json"))); - let mut contents = String::new(); - try!(f.read_to_string(&mut contents)); + let contents = try!(paths::read(&self.checkout_path.join("config.json"))); let config = try!(json::decode(&contents)); Ok(config) } @@ -331,7 +329,7 @@ impl<'cfg> RegistrySource<'cfg> { pkg))) } - try!(try!(File::create(&dst)).write_all(resp.get_body())); + try!(paths::write(&dst, resp.get_body())); Ok(dst) } diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index 88d0aacc6..21aa840b7 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -12,7 +12,7 @@ use std::path::{Path, PathBuf}; use rustc_serialize::{Encodable,Encoder}; use toml; use core::{MultiShell, Package}; -use util::{CargoResult, ChainError, Rustc, internal, human}; +use util::{CargoResult, ChainError, Rustc, internal, human, paths}; use util::toml as cargo_toml; @@ -509,11 +509,11 @@ pub fn set_config(cfg: &Config, loc: Location, key: &str, Location::Project => unimplemented!(), }; try!(fs::create_dir_all(file.parent().unwrap())); - let mut contents = String::new(); - let _ = File::open(&file).and_then(|mut f| f.read_to_string(&mut contents)); + let contents = paths::read(&file).unwrap_or(String::new()); let mut toml = try!(cargo_toml::parse(&contents, &file)); toml.insert(key.to_string(), value.into_toml()); - let mut out = try!(File::create(&file)); - try!(out.write_all(toml::Value::Table(toml).to_string().as_bytes())); + + let contents = toml::Value::Table(toml).to_string(); + try!(paths::write(&file, contents.as_bytes())); Ok(()) } diff --git a/src/cargo/util/paths.rs b/src/cargo/util/paths.rs index 7cc7d619e..1f08ea6dd 100644 --- a/src/cargo/util/paths.rs +++ b/src/cargo/util/paths.rs @@ -1,5 +1,7 @@ use std::env; use std::ffi::{OsStr, OsString}; +use std::fs::File; +use std::io::prelude::*; use std::path::{Path, PathBuf, Component}; use util::{human, internal, CargoResult, ChainError}; @@ -58,12 +60,33 @@ pub fn without_prefix<'a>(a: &'a Path, b: &'a Path) -> Option<&'a Path> { Some(y) => match a.next() { Some(x) if x == y => continue, _ => return None, - }, + }, None => return Some(a.as_path()), } } } +pub fn read(path: &Path) -> CargoResult { + (|| -> CargoResult { + let mut ret = String::new(); + let mut f = try!(File::open(path)); + try!(f.read_to_string(&mut ret)); + Ok(ret) + }).chain_error(|| { + internal(format!("failed to read `{}`", path.display())) + }) +} + +pub fn write(path: &Path, contents: &[u8]) -> CargoResult<()> { + (|| -> CargoResult<()> { + let mut f = try!(File::create(path)); + try!(f.write_all(contents)); + Ok(()) + }).chain_error(|| { + internal(format!("failed to write `{}`", path.display())) + }) +} + #[cfg(unix)] pub fn path2bytes(path: &Path) -> CargoResult<&[u8]> { use std::os::unix::prelude::*; -- 2.30.2